iT邦幫忙

2021 iThome 鐵人賽

DAY 4
0
自我挑戰組

golang 後端菜雞工程師學習雜記系列 第 4

Day4 理解 golang slice 用法及原理 IV

  • 分享至 

  • xImage
  •  

這篇主要寫兩個主題,作為 理解 golang slice 用法及原理 系列的結尾 :

  • nil slice 和 empty slice
  • slice 的常用操作,內容主要來自 SliceTricks - go wiki,幾乎所有想得到的 slice 操作都在其中。

nil slice 和 zero length slice

var arr1 []int   // nil slice
arr2 := []int{}  // empty slice

nil slice 代表的是什麼都沒有, empty slice 代表長度為 0 的 slice。

再拿寶特瓶的例子出來比喻,empty slice 代表你有一個不能裝水的寶特瓶,nil slice 代表你連寶特瓶都沒有。
在 go 的語法中 len(arr1)len(arr2) 都為 0,這設計很直覺,因為兩者都沒水啊。

在大部分情況,這兩瓶不能喝水的寶特瓶,意義都是一樣的。 這代表著在大部分情況下不需要特別去判斷 slice 是 nil 還是 empty。通常只使用 len(arr1) == 0 判斷,就去創建一個 slice,或是做其他事情。

但是但是,就是會有例外。你拿著不能裝水的寶特瓶去了回收廠可以換錢,但是你雙手空空去回收場是換不到錢的,對你來說兩者都不能裝水,意義是一樣的,但是對回收廠來說完全是不同的意義。
看一個實際案例,如果使用 empty slice 和 nil slice 去 marshall 的結果是不一樣的,請看程式碼。

arr1 := []int{}
arr1M, _ := json.Marshal(arr1)
fmt.Println(string(arr1M))  // print []

var arr2 []int
arr2M, _ := json.Marshal(arr2)
fmt.Println(string(arr2M))  // print null

slice 的各種操作

將 a slice 複製一份到 b

b := make([]T, len(a))

刪除第 i 個元素,注意: 這不適用於指標型態或是含有指標型態的 struct。這將會造成 a 的最後一個元素無法被 gc 回收 (memory leak)

a = append(a[:i], a[i+1:]...)

刪除第 i 個元素,適用於指標型態或是含有指標型態的 struct

copy(a[i:], a[i+1:])
a[len(a)-1] = nil // or the zero value of T
a = a[:len(a)-1]

刪除第 i 到 j - 1 個元素,注意: 這不適用於指標型態或是含有指標型態的 struct。這可能會造成 a 的最後 j - i 個元素無法被 gc 回收 (memory leak)

a = append(a[:i], a[j:]...)

刪除第 i 到 j - 1 個元素,適用於指標型態或是含有指標型態的 struct。

copy(a[i:], a[j:])
for k, n := len(a)-j+i, len(a); k < n; k++ {
	a[k] = nil // or the zero value of T
}
a = a[:len(a)-j+i]

插入一個元素在第 i 和 i + 1 個元素中間

s = append(s, 0 /* use the zero value of the element type */)
copy(s[i+1:], s[i:])
s[i] = x

Reference


上一篇
Day3 理解 golang slice 用法及原理 III
下一篇
Day5 休息一日思考下一步
系列文
golang 後端菜雞工程師學習雜記18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言